/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DataAccessor;

import Config.ConfigCtrl;
import Config.ConfigSetting;
import CrlException.CrlException;
import java.io.File;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;

/**
 *
 * @author CUHUUHOANG
 */
public class XMLAccessor {
    public static String configPathString = ConfigCtrl.getAbsPath("./ConfigCorolo.xml");//windows
    public static String[] xmlNode = new String[]{
        "maxThread",
        "Depth",
        "hostMySQL",
        "databaseName",
        "username",
        "password",
        "ExtractorJarFile",
        "downloadImage",
        "userProxy",
        "proxyHost",
        "proxyPort",
        "imageDir",
        "restartCrawling"
    };
    private static File fileXML;

    public static boolean DataXMLExisted() {
        File f = new File(configPathString);
        return f.exists();
    }

    public static void DeleteConfigXML() {
        if (DataXMLExisted()) {
            fileXML = new File(configPathString);
            fileXML.delete();
        }
    }


    public static void ReadConfigXML() throws CrlException {
        ConfigSetting cs= new ConfigSetting();
        cs.SetDefaultValue();
        // XML existed
        if (DataXMLExisted()) {
            fileXML = new File(configPathString);
            LoadData(fileXML);
        } // XML didn't exist
        else {
            WriteConfigXML();
            fileXML = new File(configPathString);
        }
    }

    private static void LoadData(File xml) throws CrlException {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(xml);
            doc.getDocumentElement().normalize();
            
            NodeList nList = doc.getElementsByTagName("CONFIG");
            Node nNode = nList.item(0);
            if(nNode.getNodeType() == Node.ELEMENT_NODE){
                Element eElement = (Element) nNode;

                ConfigSetting.maxThread = SafeConvertStringToInt( eElement.getElementsByTagName(xmlNode[0]).item(0).getTextContent(), 8);
                ConfigSetting.depth = SafeConvertStringToInt(eElement.getElementsByTagName(xmlNode[1]).item(0).getTextContent(), 0);
                ConfigSetting.hostMySQL = eElement.getElementsByTagName(xmlNode[2]).item(0).getTextContent();
                ConfigSetting.databaseName = eElement.getElementsByTagName(xmlNode[3]).item(0).getTextContent();
                ConfigSetting.username = eElement.getElementsByTagName(xmlNode[4]).item(0).getTextContent();
                ConfigSetting.password = eElement.getElementsByTagName(xmlNode[5]).item(0).getTextContent();
                ConfigSetting.ExtractorJarFile = eElement.getElementsByTagName(xmlNode[6]).item(0).getTextContent();
                ConfigSetting.downloadImage = SafeConvertStringToBoolean(eElement.getElementsByTagName(xmlNode[7]).item(0).getTextContent(), true);
                ConfigSetting.useProxy = SafeConvertStringToBoolean(eElement.getElementsByTagName(xmlNode[8]).item(0).getTextContent(), false);
                ConfigSetting.proxyHost = eElement.getElementsByTagName(xmlNode[9]).item(0).getTextContent();
                ConfigSetting.proxyPort = eElement.getElementsByTagName(xmlNode[10]).item(0).getTextContent();
                ConfigSetting.imageDir = eElement.getElementsByTagName(xmlNode[11]).item(0).getTextContent();
                ConfigSetting.restartCrawling = SafeConvertStringToBoolean(eElement.getElementsByTagName(xmlNode[12]).item(0).getTextContent(), false);

            
            }
            
        } catch (Exception ex) {
            throw new CrlException(ex.getMessage());
        }
    }

    public static void WriteConfigXML() throws CrlException {
        WriteConfigXML(ConfigSetting.maxThread,
                ConfigSetting.depth,
                ConfigSetting.hostMySQL,
                ConfigSetting.databaseName,
                ConfigSetting.username,
                ConfigSetting.password,
                ConfigSetting.ExtractorJarFile,
                ConfigSetting.downloadImage,
                ConfigSetting.useProxy,
                ConfigSetting.proxyHost,
                ConfigSetting.proxyPort,
                ConfigSetting.imageDir,
                ConfigSetting.restartCrawling);
    }

    public static void WriteConfigXML(int maxThread, int depth, String hostMySQL, String databaseName
            , String username, String password, String extractorJarFile, boolean downloadImage
            , boolean useProxy, String proxyHost, String proxyPort, String imageDir, boolean restartCrawling) throws CrlException {
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

            // root
            Document doc = docBuilder.newDocument();

            Element rootElement = doc.createElement("COROLO");
            doc.appendChild(rootElement);

            // Config
            Element configNode = doc.createElement("CONFIG");
            rootElement.appendChild(configNode);

            // Node
            Element maxThreadNode = doc.createElement(xmlNode[0]);
            maxThreadNode.appendChild(doc.createTextNode(Integer.toString(maxThread)));
            configNode.appendChild(maxThreadNode);

            Element depthNode = doc.createElement(xmlNode[1]);
            depthNode.appendChild(doc.createTextNode(Integer.toString(depth)));
            configNode.appendChild(depthNode);

            Element hostMySQLNode = doc.createElement(xmlNode[2]);
            hostMySQLNode.appendChild(doc.createTextNode(hostMySQL));
            configNode.appendChild(hostMySQLNode);

            Element databaseNameNode = doc.createElement(xmlNode[3]);
            databaseNameNode.appendChild(doc.createTextNode(databaseName));
            configNode.appendChild(databaseNameNode);

            Element usernameNode = doc.createElement(xmlNode[4]);
            usernameNode.appendChild(doc.createTextNode(username));
            configNode.appendChild(usernameNode);

            Element passwordNode = doc.createElement(xmlNode[5]);
            passwordNode.appendChild(doc.createTextNode(password));
            configNode.appendChild(passwordNode);

            Element extractJarFileNode = doc.createElement(xmlNode[6]);
            extractJarFileNode.appendChild(doc.createTextNode(extractorJarFile));
            configNode.appendChild(extractJarFileNode);

            Element downloadImageNode = doc.createElement(xmlNode[7]);
            downloadImageNode.appendChild(doc.createTextNode(Boolean.toString(downloadImage)));
            configNode.appendChild(downloadImageNode);

            Element useProxyNode = doc.createElement(xmlNode[8]);
            useProxyNode.appendChild(doc.createTextNode(Boolean.toString(useProxy)));
            configNode.appendChild(useProxyNode);

            Element proxyHostNode = doc.createElement(xmlNode[9]);
            proxyHostNode.appendChild(doc.createTextNode(proxyHost));
            configNode.appendChild(proxyHostNode);

            Element proxyPortNode = doc.createElement(xmlNode[10]);
            proxyPortNode.appendChild(doc.createTextNode(proxyPort));
            configNode.appendChild(proxyPortNode);

            Element imageDirNode = doc.createElement(xmlNode[11]);
            imageDirNode.appendChild(doc.createTextNode(imageDir));
            configNode.appendChild(imageDirNode);

            Element restartCrawlingNode = doc.createElement(xmlNode[12]);
            restartCrawlingNode.appendChild(doc.createTextNode(Boolean.toString(restartCrawling)));
            configNode.appendChild(restartCrawlingNode);

            //write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);

            StreamResult result = new StreamResult(new File(configPathString));
            transformer.transform(source, result);

        } catch (Exception ex) {
            throw new CrlException(ex.getMessage());
        } 
    }
    
    private static int SafeConvertStringToInt(String str, int defaultValue){
        try{
            int result = Integer.parseInt(str);
            return result;
        }
        catch ( Exception ex){
            return defaultValue;
        }
    }
    
    private static boolean SafeConvertStringToBoolean( String str, boolean defaultValue){
        try{
            boolean result = Boolean.parseBoolean(str);
            return result;
        }
        catch ( Exception ex){
            return defaultValue;
        }
    }
}
